/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jili.ubert;

import com.alibaba.fastjson.JSON;
import com.jili.ubert.code.server2client.Price;
import com.jili.ubert.dao.NewHibernateUtil;
import com.jili.ubert.dao.sim.ClearingPrice;
import com.jili.ubert.dao.sim.ObjEtf;
import com.jili.ubert.dao.sim.ObjEtflist;
import com.jili.ubert.dao.sim.ObjInfo;
import com.jili.ubert.dao.sim.ObjNewstock;
import com.jili.ubert.dao.sim.ObjStructuredfundBase;
import com.jili.ubert.dao.sim.ObjStructuredfundPart;
import com.jili.ubert.dao.sim.TradeSimOrderquene;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;

/**
 *
 * @author ChengJiLi
 */
public class ResourceManager {
//    public static HashMap<Integer,TradeSimOrderquene> OrderQuene = new HashMap();

    private static final Log log = LogFactory.getLog(ResourceManager.class);
    /**
     * OrderQuenes,key:obj_MarketCode;value:OrderQuene
     * OrderQuene,key:OrderID(int),value:TradeSimOrderquene:DAO存数据库的对象实例
     * 压力测试决定是否使用 多线程处理写数据库，匹配成交
     */
    public static ConcurrentHashMap<String, OrderQuene> OrderQuenes = new ConcurrentHashMap();
    public static ConcurrentHashMap<Integer, TradeSimOrderquene> Orderlist = new ConcurrentHashMap();
    public static ConcurrentHashMap<String, Price> PriceQuenes = new ConcurrentHashMap();
    public static ConcurrentHashMap<String, ObjInfo> ObjInfos = new ConcurrentHashMap();
    public static ConcurrentHashMap<String, ObjEtf> ObjEtfs = new ConcurrentHashMap();
    public static ConcurrentHashMap<String, ObjEtflistMap> ObjEtflists = new ConcurrentHashMap();
    public static ConcurrentHashMap<String, ObjNewstock> ObjNewstocks = new ConcurrentHashMap();
    public static ConcurrentHashMap<String, ObjStructuredfundBase> ObjStructuredfundBases = new ConcurrentHashMap();
    public static ConcurrentHashMap<String, FundPartMap> ObjStructuredfundParts = new ConcurrentHashMap();
    public static int gv_entrustNo = -1;
    public static int gv_exeSequenceNo = 1;


    //撮合成交；只有B S买卖的单子；无特殊委托，而且只有普通现价单

    public static void Match(OrderQuene orderQuene, Price price, String makerCode, int type) {
        switch (makerCode) {
            case "S": {
                Match_SH(orderQuene, price, type);
                break;
            }
            case "A": {
                Match_SH(orderQuene, price, type);
                break;
            }
            case "F": {
                Match_FC(orderQuene, price, type);
                break;
            }
            case "C": {
                Match_FC(orderQuene, price, type);
                break;
            }
            case "Z": {
                Match_FC(orderQuene, price, type);
                break;
            }
            case "D": {
                Match_FC(orderQuene, price, type);
                break;
            }
            case "H": {
                Match_HK(orderQuene, price, type);
                break;
            }
            case "K": {
                Match_HK(orderQuene, price, type);
                break;
            }
            case "L": {

                break;
            }
        }

    }

    private static void MatchImp(OrderQuene orderQuene, Price price) {
        float price0 = price.getLastPrice();
        int qty0 = price.getLastQty();
        Iterator iter = orderQuene.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            TradeSimOrderquene order = (TradeSimOrderquene) entry.getValue();
            log.info("待成交队列单：" + JSON.toJSONString(order));
            int orderid = (int) entry.getKey();
            if (order.getBs().equals("B")) {
                if (order.getOrderPrice() >= price0) {
                    if (order.getWorkingQty() <= qty0) {//成交getWorkingQty，删除撮合队列
                        //修订最新队列数据
                    //    order.setWorkingQty(0);
                    //    order.setExeQty(order.getWorkingQty() + order.getExeQty());
                        //回报
                        ReportManager.ExecuteReport(order, order.getWorkingQty(), price0, 1, gv_entrustNo);
                        //删除库，表
                        NewHibernateUtil.delte(order);

                        ResourceManager.OrderQuenes.get(order.getObj() + "_" + order.getMarketCode()).remove(orderid);
                        ResourceManager.Orderlist.remove(orderid);
                    } else {//成交qty0；修改撮合队列
                        order.setWorkingQty(order.getWorkingQty() - qty0);
                        order.setExeQty(qty0 + order.getExeQty());
                        ReportManager.ExecuteReport(order, qty0, price0, 1, gv_entrustNo);
                        NewHibernateUtil.update(order);
                        ResourceManager.OrderQuenes.get(order.getObj() + "_" + order.getMarketCode()).put(orderid, order);
                        ResourceManager.Orderlist.put(orderid, order);
                    }
                }
            } else {
                if (order.getOrderPrice() <= price0) {
                    if (order.getWorkingQty() <= qty0) {//成交getWorkingQty，删除撮合队列
                        //修订最新队列数据
                    //    order.setWorkingQty(0);
                    //    order.setExeQty(order.getWorkingQty() + order.getExeQty());
                        //回报
                        ReportManager.ExecuteReport(order, order.getWorkingQty(), price0, 1, gv_entrustNo);
                        //删除库，表
                        NewHibernateUtil.delte(order);

                        ResourceManager.OrderQuenes.get(order.getObj() + "_" + order.getMarketCode()).remove(orderid);
                        ResourceManager.Orderlist.remove(orderid);
                    } else {//成交qty0；修改撮合队列
                        order.setWorkingQty(order.getWorkingQty() - qty0);
                        order.setExeQty(qty0 + order.getExeQty());
                        ReportManager.ExecuteReport(order, qty0, price0, 1, gv_entrustNo);
                        NewHibernateUtil.update(order);
                        ResourceManager.OrderQuenes.get(order.getObj() + "_" + order.getMarketCode()).put(orderid, order);
                        ResourceManager.Orderlist.put(orderid, order);
                    }
                }
            }
        }

    }

    private static void Match_SH(OrderQuene orderQuene, Price price, int type) {
        /*
         1.判断订单价格类型，市价直接成交
         2.判断限价单价格与最新价，最新价优先，按买手最低价，卖手高价成交
         3.
         */
        MatchImp(orderQuene, price);
    }

    private static void Match_FC(OrderQuene orderQuene, Price price, int type) {
        MatchImp(orderQuene, price);
    }

    private static void Match_HK(OrderQuene orderQuene, Price price, int type) {
        MatchImp(orderQuene, price);
    }

    public ResourceManager() {
        Session session = NewHibernateUtil.getOpenSession();
        String querysimOrder = "from TradeSimOrderquene";
        String queryobj = "from ObjInfo";
        String querynewStock = "from ObjNewstock";
        String queryeft = "from ObjEtf";
        String queryetflist = "from ObjEtflist";
        String queryfundbase = "from ObjStructuredfundBase";
        String queryfundpart = "from ObjStructuredfundPart";
        String querycealringprice = "from ClearingPrice";
        List<ClearingPrice> list7 = session.createQuery(querycealringprice).list();
        for (ClearingPrice data : list7) {
            Price price = new Price();
            price.setLastPrice(data.getAlcprice());
            price.setObj(data.getObj());
            price.setMaketCode(data.getMarketCode());
            price.setLNC(data.getClosePrice());
            price.setClassCode(data.getClassCode());

            PriceQuenes.put(data.getObj() + "_" + data.getMarketCode(), price);
        }
        //TradeSimOrderquene

        List<TradeSimOrderquene> list = session.createQuery(querysimOrder).list();
        for (TradeSimOrderquene data : list) {
            Orderlist.put(data.getOrderId(), data);
            if (!OrderQuenes.containsKey(data.getObj() + "_" + data.getMarketCode())) {
                OrderQuene oq = new OrderQuene();
                OrderQuenes.put(data.getObj() + "_" + data.getMarketCode(), oq);
            }
            OrderQuenes.get(data.getObj() + "_" + data.getMarketCode()).put(data.getOrderId(), data);
        }
        //ObjInfo
        List<ObjInfo> list1 = session.createQuery(queryobj).list();
        for (ObjInfo data : list1) {
            ObjInfos.put(data.getObjid(), data);
        }
        //ObjNewstock
        List<ObjNewstock> list2 = session.createQuery(querynewStock).list();
        for (ObjNewstock data : list2) {
            ObjNewstocks.put(data.getObj() + "_" + data.getMarketCode(), data);
        }
        //ObjEtf
        List<ObjEtf> list3 = session.createQuery(queryeft).list();
        for (ObjEtf data : list3) {
            ObjEtfs.put(data.getEtfid(), data);
        }
        //ObjEtflist
        List<ObjEtflist> list4 = session.createQuery(queryetflist).list();
        for (ObjEtflist data : list4) {
            if (!ObjEtflists.containsKey(data.getEtfid())) {
                ObjEtflistMap oe = new ObjEtflistMap();
                ObjEtflists.put(data.getEtfid(), oe);
            }
            ObjEtflists.get(data.getEtfid()).put(data.getObj() + "_" + data.getMarketCode(), data);
        }
        //ObjStructuredfundBase
        List<ObjStructuredfundBase> list5 = session.createQuery(queryfundbase).list();
        for (ObjStructuredfundBase data : list5) {
            ObjStructuredfundBases.put(data.getObj() + "_" + data.getMarketCode(), data);
        }
        //
        List<ObjStructuredfundPart> list6 = session.createQuery(queryfundpart).list();
        for (ObjStructuredfundPart data : list6) {
            if (!ObjStructuredfundParts.containsKey(data.getObj() + "_" + data.getMarketCode())) {
                FundPartMap oe = new FundPartMap();
                ObjStructuredfundParts.put(data.getObj() + "_" + data.getMarketCode(), oe);
            }
            ObjStructuredfundParts.get(data.getObj() + "_" + data.getMarketCode()).put(data.getObj() + "_" + data.getMarketCode(), data);
        }
        list = null;
        list1 = null;
        list2 = null;
        list3 = null;
        list4 = null;
        list5 = null;
        list6 = null;
        querysimOrder = null;
        queryobj = null;
        querynewStock = null;
        queryeft = null;
        queryetflist = null;
        queryfundbase = null;
        queryfundpart = null;
        NewHibernateUtil.closeSession(session);
    }

    public static String getRegionID(String mk) {
        if (mk.equals("H")) {
            return "H";
        } else if (mk.equals("L") && mk.equals("K")) {
            return "A";
        } else {
            return "C";
        }
    }
}
